package io.renren.common.redis;

import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * @author yun lang
 * @version 1.0
 * @description: Redis锁
 * @date 2024/10/21 10:18
 */
@Component
public class RedisLock {
    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(RedisLock.class);

    private static final String LOCK_PREFIX = "api:lock:";
    // seconds
    private static final long LOCK_EXPIRE_TIME = 10;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public boolean tryLock(String lockKey, String requestId) {
        String lockKeyWithPrefix = LOCK_PREFIX + lockKey;
        boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKeyWithPrefix, requestId, LOCK_EXPIRE_TIME, TimeUnit.SECONDS);
        return locked;
    }

    public boolean unlock(String lockKey, String requestId) {
        String lockKeyWithPrefix = LOCK_PREFIX + lockKey;
        String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        RedisScript<Long> redisScript = new DefaultRedisScript<>(luaScript, Long.class);
        Long result = redisTemplate.execute(redisScript, Collections.singletonList(lockKeyWithPrefix), requestId);
        return result != null && result == 1L;
    }
}
